// import ws from "ws";
// import { WebSocketServer } from "./WebSocketServer";
// import { LNode } from "./lNode";
// import { RedisKeys } from "../../etc/redisKeys";
// import g from "../../common/g";
// import { IService, IPack } from "../../etc/lyuInterface";
// import { utils } from "../../util/utils";
// import lyu from "../../lyu";
// import { conf } from "../../etc/conf";
// import lyuEvent from "../../event/lyuEvent";

// // import schedule from "node-schedule";
// var log = console.log;

// var __Call_Back_Seed__ = 1000;
// const __Default_FuncID__ = 1000;
// const __Send_Key__ = 100000;

// export default class LAdapter extends WebSocketServer {
//     /**
//      * 节点临时列表，仅用于临时存储未得到名称的节点
//      */
//     private nodeList: LNode[] = [];
//     /**
//      * 节点名称表 [节点名称]： 节点
//      */
//     private nodeNameMap: { [x: string]: LNode } = {};
//     /**
//      * 回调超时列表
//      */
//     private timeOutList: { [x: number]: number } = {};
//     /**
//      * 回调列表
//      */
//     private callbackList: { [x: number]: (...res: any) => void } = {};
//     /**
//      * 等待列表
//      *  用于send失败，服务连接后，再次发送数据
//      */
//     private waitList: { [x: string]: { node: string, func: string, data: any[] }[] } = {};
//     /**
//      * 事件列表
//      */
//     private funcList: { [x: string]: Function } = {};

//     constructor(port: number) {
//         super({ port: port });
//         this.listen();

//         log("[Adapter] 启动完成，内部网络端口：", port);

//         this.register("service", this.newNode.bind(this));
//         this.register("ping", this.pong.bind(this));
//     }

//     /**
//      * 异步初始化
//      *  完成注册和开启刷新定时任务
//      */
//     async init() {
//         await this.refresh();
//         this.update();
//     }

//     /**
//      * 定时器，每秒循环一场
//      */
//     private dt = 0;
//     private update() {
//         this.dt++;
//         if (this.dt % 30 == 0) {
//             this.refresh();
//         }
//         this.checkTimeOut();
//         this.checkOffline();
//         setTimeout(this.update.bind(this), 1000);
//     }

//     /**
//      * 刷新redis存储信息
//      */
//     private async refresh() {
//         let regData = {
//             name: g.name,
//             port: g.port,
//             host: g.host,
//         };
//         // 刷新redis 服务信息
//         await lyu.lRedis.set(RedisKeys.getServiceGroupKeys(g.name), JSON.stringify(regData));
//         // 设置信息过期时间
//         await lyu.lRedis.expire(RedisKeys.getServiceGroupKeys(g.name), 40);
//         // 获取所有服务连接信息
//         let serviceList = await lyu.lRedis.keys(RedisKeys.getServiceGroupKeys("*"));

//         let livingService: string[] = [];// 现有服务列表
//         for (let s of serviceList) {
//             let c = await lyu.lRedis.get(s);
//             if (c == null) {
//                 continue;
//             }
//             let service: IService = utils.safeJson(c);// JSON.parse(s);

//             if (service) {
//                 livingService.push(service.name);
//                 // 如果存在连接，则跳过
//                 if (this.nodeNameMap[service.name]) {
//                     continue;
//                 }
//                 // 如果是自己，跳过
//                 if (service.name == g.name) {
//                     continue;
//                 }
//                 // 不存在的连接，建立连接
//                 await this.createNewNode(service);
//             }
//         }

//         // 检查现有与存储的是否有差异，删除不存在的服务
//         for (const serviceName in this.nodeNameMap) {
//             if (Object.prototype.hasOwnProperty.call(this.nodeNameMap, serviceName)) {
//                 const node = this.nodeNameMap[serviceName];
//                 if (livingService.indexOf(node.name) == -1) {
//                     this.removeNode(node.name);
//                 }
//             }
//         }
//     }

//     private checkTimeOut() {
//         for (const callBackId in this.timeOutList) {
//             if (Object.prototype.hasOwnProperty.call(this.timeOutList, callBackId)) {
//                 const dt = this.timeOutList[callBackId];
//                 if (this.dt >= dt) {
//                     let func = this.callbackList[callBackId];
//                     if (func != undefined) {
//                         log(`[Adapter] 函数响应超时：${callBackId} ${String(func)}`);
//                         func(null);
//                         delete this.callbackList[callBackId];
//                         delete this.timeOutList[callBackId];
//                     }
//                 }
//             }
//         }
//     }

//     private checkOffline() {
//         for (const nodeName in this.nodeNameMap) {
//             if (Object.prototype.hasOwnProperty.call(this.nodeNameMap, nodeName)) {
//                 const node = this.nodeNameMap[nodeName];
//                 if (node.isSalve) {
//                     this.call(node.name, "ping", "", (res: any) => {
//                         if (res == null) {
//                             log(`[Adapter]: 服务[${node.name}] 失去响应!`);
//                             node.offtimes++;
//                             if (node.offtimes > 3) {
//                                 log(`[Adapter]: 服务[${node.name}] 断开连接!`);
//                                 this.removeNode(node.name);
//                             }
//                             return;
//                         }
//                         node.offtimes = 0;
//                     }, 10);
//                 }
//             }
//         }
//     }

//     async createNewNode(service: IService) {
//         let node = new LNode();
//         node.name = service.name;
//         node.host = service.host;
//         node.port = service.port;
//         node.isSalve = true;

//         if (await node.connect(service.host, service.port)) {
//             this.nodeNameMap[service.name] = node;
//             this.send(service.name, "service", { name: g.name, host: g.host, port: g.port });
//             this.checkNewNode(service.name);
//         } else {
//             log(`[Adapter] 无法连接到服务[${service.name}], 连接地址:${service.host}:${service.port}`);
//         }
//     }

//     onConnection(socket: ws) {
//         // TODO: 处理重复连接
//         let node = new LNode(socket);
//         socket.on("message", (data: ws.Data) => {
//             this.onReceive(node, data);
//         });

//         socket.on("close", (w: ws, code: number, reason: string) => {
//             node.onClose(code, reason);
//         });

//         this.nodeList.push(node);
//     }

//     onClose(error?: Error): void {
//         lyu.lRedis.del(RedisKeys.getServiceGroupKeys(g.name));
//     }

//     private newNode(data: any, node: LNode) {
//         node.name = data.name;
//         node.port = data.port;
//         node.host = data.host;
//         this.nodeNameMap[data.name] = node;

//         let index = this.nodeList.indexOf(node);
//         if (index != -1) {
//             // 删除临时
//             this.nodeList.splice(index, 1);
//         }
//         lyu.event.emit(lyuEvent.getServiceConnectedKey(data.name));
//         this.checkNewNode(data.name);
//     }

//     /**
//      * 检查新节点连入
//      *  主要用于针对 强发送 方法，节点不存在，或发送失败后，存储信息
//      *  等节点连接后，再次发送给目标节点
//      * @param nodeName 目标节点名字
//      */
//     async checkNewNode(nodeName: string) {
//         for (const serviceName in this.waitList) {
//             if (Object.prototype.hasOwnProperty.call(this.waitList, serviceName)) {
//                 if (serviceName == nodeName) {
//                     const dataList = this.waitList[serviceName];
//                     for (let i = dataList.length - 1; i >= 0; i--) {
//                         let data = dataList[i];
//                         let ret = await this.fsend(data.node, data.func, data.data);
//                         if (ret == undefined) {
//                             this.waitList[serviceName].splice(i, 1);
//                         }
//                     }
//                     if (this.waitList[serviceName].length == 0) {
//                         delete this.waitList[serviceName];
//                     }
//                 }
//             }
//         }
//     }

//     private pong() {
//         return "pong";
//     }


//     removeNode(index: string) {
//         let node = this.nodeNameMap[index];

//         if (node) {
//             delete this.nodeNameMap[node.name];
//         }
//     }

//     register(cmd: string, func: Function) {
//         this.funcList[cmd] = func;
//     }

//     unRegister(cmd: string) {
//         if (this.funcList[cmd]) {
//             delete this.funcList[cmd];
//         }
//     }

//     async onReceive(node: LNode, data: ws.Data) {
//         let m = data as string;

//         let req: IPack = JSON.parse(m);
//         if (req.callBackId && req.callBackId < __Send_Key__) {
//             // 生产者
//             if (this.callbackList[req.callBackId]) {
//                 if (Array.isArray(req.data)) {
//                     this.callbackList[req.callBackId](...req.data);
//                 } else {
//                     this.callbackList[req.callBackId](req.data);
//                 }
//                 // 消费完删除
//                 delete this.callbackList[req.callBackId];
//                 if (this.timeOutList[req.callBackId]) {
//                     delete this.timeOutList[req.callBackId];
//                 }
//             }
//             return;
//         }
//         // 消费者
//         let res: any = undefined;
//         let func = this.funcList[req.func];
//         if (func) {
//             let msg = req.data;
//             if (utils.empty(msg)) {
//                 res = await func(req.data, node);
//             } else {
//                 res = await func(...req.data, node);
//             }

//         } else {
//             log(`[Adapter] 注册函数不存在：${String(req.func)}`);
//             res = conf.lyuError;
//         }

//         if (req.callBackId && res) {
//             let resPack: IPack = {
//                 func: "",
//                 data: res,
//                 callBackId: req.callBackId - __Send_Key__,
//             }
//             node.send(resPack);
//         }
//     }

//     send(name: string, func: string, ...data: any) {
//         let node = this.nodeNameMap[name];
//         if (node) {
//             let pack: IPack = {
//                 func: func,
//                 data: data,
//             }
//             node.send(pack);
//         }
//     }

//     async fsend(name: string, func: string, ...data: any) {
//         let node = this.nodeNameMap[name];
//         if (node) {
//             let pack: IPack = {
//                 func: func,
//                 data: data,
//             }
//             let ret = await node.send(pack);
//             if (ret) {
//                 this.addToWait(name, func, data);
//             }
//         }
//         this.addToWait(name, func, data);
//     }

//     addToWait(name: string, func: string, ...data: any) {
//         if (this.waitList[name] == undefined) {
//             this.waitList[name] = [];
//         }
//         this.waitList[name].push({ node: name, func: func, data: data });
//     }

//     broadcast(func: string, ...data: any) {
//         for (const key in this.nodeNameMap) {
//             if (Object.prototype.hasOwnProperty.call(this.nodeNameMap, key)) {
//                 const node = this.nodeNameMap[key];
//                 if (node) {
//                     let pack: IPack = {
//                         func: func,
//                         data: data,
//                     }
//                     node.send(pack);
//                 }
//             }
//         }
//     }

//     call(name: string, func: string, data: any, callback: (res: any) => void, timeout: number) {
//         __Call_Back_Seed__++;
//         // 避免消息号过多
//         if (__Call_Back_Seed__ >= __Send_Key__) {
//             __Call_Back_Seed__ = __Default_FuncID__;
//         }
//         let funcid = __Call_Back_Seed__ + __Send_Key__;
//         this.callbackList[__Call_Back_Seed__] = callback;
//         if (timeout != 0) {
//             this.timeOutList[__Call_Back_Seed__] = this.dt + timeout;
//         }
//         // this.emit(name, buffer);
//         let node = this.nodeNameMap[name];
//         if (node) {
//             let pack: IPack = {
//                 func: func,
//                 data: data,
//                 callBackId: funcid,
//             }
//             node.send(pack);
//         } else {
//             callback(conf.lyuError);
//         }
//     }


// }